<?php
namespace Tyrone\Model;
use Medoo\Medoo;

class Base
{
    const PARTITION_NAME_MAX = 'p_max';
    /* @var $database \Tyrone\Lib\SafeMedoo */
    protected $database;
    private $alias;
    private $db_name;
    protected $table;
    public function __construct($database,$db_name='')
    {
        $this->database = $database;
        $this->db_name = $db_name;
    }

    public function mysqlLog(){
        return $this->database->log();
    }
    public function getTable(){
        return $this->table;
    }
    public static function getLastPartition($mysql,$table)
    {
        $result = $mysql->query("
        SELECT 
            PARTITION_NAME,
            PARTITION_DESCRIPTION 
        FROM information_schema.PARTITIONS 
        WHERE TABLE_SCHEMA = :db
          AND TABLE_NAME = :tab
          AND PARTITION_NAME != '".self::PARTITION_NAME_MAX."'
        ORDER BY TO_DAYS(REPLACE(PARTITION_DESCRIPTION , '''', '')) DESC
        LIMIT 1
    ", [':db'=>'center',':tab'=>$table])->fetchAll(\PDO::FETCH_ASSOC);

        return $result ? $result[0] : null;
    }


    public static function getTablePrimaryKey($mysql,$tableName){
        // 获取表信息
        $tableInfo = $mysql->query("SHOW KEYS FROM {$tableName} WHERE Key_name = 'PRIMARY'")->fetchAll(\PDO::FETCH_ASSOC);
        $primaryKey = [];
        foreach ($tableInfo as $info) {
            $primaryKey[] = $info['Column_name'];
        }
        return $primaryKey;
    }

    /**
     * @param $connectionName
     * @param string $table 表
     * @param string $field 分区字段
     * @param string $type 类型
     * @param int $num 数量
     * @param bool $execute 直接执行
     * @param null $start 开始时间戳
     * @return string
     */
    public static function partitionByRange($mysql,$table,$field,$type='month',$num=12,$execute=false,$start=null){

        if(!in_array($field,self::getTablePrimaryKey($mysql,$table))){
            return 'field not exist PrimaryKey';
        }
        $last = self::getLastPartition($mysql,$table);
        $lastDate = trim($last->PARTITION_DESCRIPTION ??'', "'"); // '2026-08-01' → 2026-08-01

        $partition = [];
        if($type=='month'){
            $start = strtotime(date('Y-m',$lastDate ? strtotime("+1 month",strtotime($lastDate)): ($start?:time())));
            for($i=0;$i<$num;$i++){
                $time = strtotime("+$i month",$start);
                $date = date('Ymd',$time);
                if(!$lastDate){
                    $name = ($i==0 ? 'less_p': 'p').date('Ym',$time-($i==0 ? 0: 1));
                }else{
                    $name = 'p'.date('Ym',strtotime("-1 month",$time));
                }
                $partition[] = "PARTITION {$name} VALUES LESS THAN ($date)";
            }
        }
        $partition_str = implode(",\n",$partition);
        $init = "PARTITION BY RANGE COLUMNS({$field})";
        if($lastDate){
            $init = 'REORGANIZE PARTITION '.self::PARTITION_NAME_MAX.' INTO';
        }
        $sql = "
        ALTER TABLE {$table}
            {$init} (
            {$partition_str},
            PARTITION p_max    VALUES LESS THAN MAXVALUE
         )";
        if($execute){
            DB::connection($connectionName)->statement($sql);
        }
        return $sql;
    }


}